home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / pc / SNNSV32.ZIP / SNNSv3.2 / kernel / sources / kr_art1.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-04-25  |  56.7 KB  |  2,338 lines

  1. /*****************************************************************************
  2.   FILE           : kr_art1.c
  3.   SHORTNAME      : 
  4.   SNNS VERSION   : 3.2
  5.  
  6.   PURPOSE        : SNNS Kernel Functions for ART1 networks
  7.   NOTES          :
  8.  
  9.   AUTHOR         : Kai-Uwe Herrmann
  10.   DATE           : 17.05.92
  11.  
  12.   CHANGED BY     : Sven Doering
  13.   IDENTIFICATION : @(#)kr_art1.c    1.7 3/15/94
  14.   SCCS VERSION   : 1.7
  15.   LAST CHANGE    : 3/15/94
  16.  
  17.              Copyright (c) 1990-1994  SNNS Group, IPVR, Univ. Stuttgart, FRG
  18.  
  19. ******************************************************************************/
  20.  
  21. #include <stdlib.h>
  22.  
  23.  
  24. #ifndef NULL /* if NULL pointer is not defined include stdio.h */
  25. #include <stdio.h>
  26. #endif
  27.  
  28.  
  29. #include "kr_const.h"
  30. #include "kr_mac.h"
  31. #include "kr_def.h"
  32. #include "kr_typ.h"
  33. #include "kr_funcs.h"
  34. #include "kernel.h"
  35. #include "glob_typ.h"
  36. #include "kr_art.h"     /*  Function prototypes for ART networks */
  37. #include "krart_df.h"   /*  Definitions for ART networks */
  38. #include "kr_art1.ph"
  39.  
  40.  
  41.  
  42. /*#################################################
  43.  
  44. GROUP: ART 1 kernel functions
  45.        by Kai-Uwe Herrmann
  46.  
  47. #################################################*/
  48.  
  49.  
  50.  
  51.  
  52.  
  53.  
  54. /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
  55. /* NOTE: Don't call this function unless net has been topologically sorted
  56.          with type ART1_TOPO_TYPE
  57. */
  58.  
  59. krui_err  kra1_init_i_act (double rho)
  60. {
  61.    int                    ret_code = KRERR_NO_ERROR;
  62.  
  63.    register struct Unit   *unit_ptr;
  64.  
  65.  
  66.    FOR_ALL_UNITS (unit_ptr) {
  67.  
  68.       switch (unit_ptr->lln) {
  69.  
  70.       case ART1_SPEC_LAY:
  71.          switch (unit_ptr->lun) {
  72.          case ART1_G1_UNIT :
  73.             unit_ptr->i_act = 0.0;
  74.             break;
  75.          case ART1_RI_UNIT :
  76.             unit_ptr->i_act = 1.0;
  77.             break;
  78.          case ART1_RG_UNIT :
  79.             unit_ptr->i_act = 1.0;
  80.             break;
  81.          case ART1_RHO_UNIT :
  82.             unit_ptr->i_act = (FlintType) rho;
  83.             break;
  84.          default :
  85.             unit_ptr->i_act = 0.0;
  86.             break;
  87.          } /*switch*/
  88.          break;
  89.  
  90.       default :
  91.          unit_ptr->i_act = 0.0;
  92.          break;
  93.       } /*switch*/
  94.  
  95.    } /*FOR_ALL_UNITS*/
  96.  
  97.  
  98.    return (ret_code);
  99.  
  100. } /* kra1_init_i_act () */
  101. /*___________________________________________________________________________*/
  102.  
  103.  
  104.  
  105.  
  106.  
  107.  
  108. /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
  109. krui_err  kra1_sort (void)
  110. {
  111.  
  112.    int                  no_of_cmp_units = 0;
  113.    int                  no_of_del_units = 0;
  114.    int                  no_of_rst_units = 0;
  115.    int                  no_of_spec_units = 0;
  116.  
  117.    TopoPtrArray         topo_ptr = topo_ptr_array;
  118.  
  119.    int                  ret_code = KRERR_NO_ERROR;  /*  reset return code  */
  120.  
  121.  
  122.  
  123.    /* initialize ART1 sorting
  124.    */
  125.    krart_init_sorting ();
  126.  
  127.  
  128.    /* get no of input units and no of recognition units
  129.    */
  130.    NoOfInputUnits         = krart_get_NoOfInputUnits ();
  131.    Art1_NoOfRecUnits      = kra1_get_NoOfRecUnits ();
  132.  
  133.  
  134.    if (NoOfInputUnits == 0) {
  135.       ret_code = KRERR_NO_INPUT_UNITS;
  136.       return (ret_code);
  137.    } /*if*/
  138.  
  139.    if (Art1_NoOfRecUnits == 0) {
  140.       TOPO_MSG_NO_OF_UNITS_IN_LAYER ("recognition");
  141.    } /*if*/
  142.  
  143.  
  144.  
  145.    /* insert a NULL pointer to topo ptr array for left limitation
  146.    */
  147.    *topo_ptr++ = NULL;
  148.  
  149.  
  150.    /* determine unit types and insert them into topo ptr array
  151.    */
  152.  
  153.    /* determine input units
  154.    */
  155.    ret_code = kra1_get_InpUnits (&topo_ptr);
  156.  
  157.    if (ret_code != KRERR_NO_ERROR) {
  158.       return (ret_code);
  159.    } /*if*/
  160.  
  161.    *topo_ptr++ = NULL;
  162.  
  163.  
  164.    /* determine comparison units
  165.    */
  166.    ret_code = kra1_get_CmpUnits (&topo_ptr, &no_of_cmp_units);
  167.  
  168.    if (ret_code != KRERR_NO_ERROR) {
  169.       return (ret_code);
  170.    } /*if*/
  171.  
  172.    if (no_of_cmp_units != NoOfInputUnits) {
  173.       TOPO_MSG_NO_OF_UNITS_IN_LAYER ("comparison");
  174.    } /*if*/
  175.  
  176.    *topo_ptr++ = NULL;
  177.  
  178.  
  179.    /* determine recognition units
  180.    */
  181.    ret_code = kra1_get_RecUnits (&topo_ptr);
  182.  
  183.    if (ret_code != KRERR_NO_ERROR) {
  184.       return (ret_code);
  185.    } /*if*/
  186.  
  187.    *topo_ptr++ = NULL;
  188.  
  189.  
  190.    /* determine delay units
  191.    */
  192.    Art1_del_layer = topo_ptr;
  193.    ret_code = kra1_get_DelUnits (&topo_ptr, &no_of_del_units);
  194.  
  195.    if (ret_code != KRERR_NO_ERROR) {
  196.       return (ret_code);
  197.    } /*if*/
  198.  
  199.  
  200.    if (no_of_del_units != Art1_NoOfRecUnits + 3) {
  201.       TOPO_MSG_NO_OF_UNITS_IN_LAYER ("delay");
  202.    } /*if*/
  203.  
  204.    *topo_ptr++ = NULL;
  205.  
  206.  
  207.    /* determine local reset units
  208.    */
  209.    ret_code = kra1_get_RstUnits (&topo_ptr, &no_of_rst_units);
  210.  
  211.    if (ret_code != KRERR_NO_ERROR) {
  212.       return (ret_code);
  213.    } /*if*/
  214.  
  215.    if (no_of_rst_units != Art1_NoOfRecUnits) {
  216.       TOPO_MSG_NO_OF_UNITS_IN_LAYER ("reset");
  217.    } /*if*/
  218.  
  219.    *topo_ptr++ = NULL;
  220.  
  221.    ret_code = kra1_get_SpecUnits (&topo_ptr, &no_of_spec_units);
  222.  
  223.    if (ret_code != KRERR_NO_ERROR) {
  224.       return (ret_code);
  225.    } /*if*/
  226.  
  227.    if (no_of_spec_units != ART1_NO_OF_SPEC_UNITS) {
  228.       TOPO_MSG_NO_OF_UNITS_IN_LAYER ("special");
  229.    } /*if*/
  230.  
  231.    *topo_ptr++ = NULL;
  232.  
  233.  
  234.    /* check if the logical type of really all units is determined
  235.    */
  236.    if (krart_check_undeterminedUnits ()) {
  237.       ret_code = topo_msg.error_code;
  238.       return (ret_code);
  239.    } /*if*/
  240.  
  241.  
  242.    /* Now check the topo ptr array
  243.    */
  244.    ret_code = kra1_TopoPtrArray ();
  245.  
  246.    if (ret_code != KRERR_NO_ERROR) {
  247.       return (ret_code);
  248.    } /*if*/
  249.  
  250.  
  251.    /* Check the sites
  252.    */
  253.  
  254.    ret_code = kra1_Sites ();
  255.  
  256.    if (ret_code != KRERR_NO_ERROR) {
  257.       return (ret_code);
  258.    } /*if*/
  259.  
  260.  
  261.    /* Check link structure
  262.    */
  263.    topo_ptr = topo_ptr_array + 1;
  264.  
  265.    /* Check links of input units
  266.    */
  267.    ret_code = kra1_LinksToInpUnits (&topo_ptr);
  268.  
  269.    if (ret_code != KRERR_NO_ERROR) {
  270.       return (ret_code);
  271.    } /*if*/
  272.  
  273.  
  274.    /* check links of comparison units
  275.    */
  276.    ret_code = kra1_LinksToCmpUnits (&topo_ptr);
  277.  
  278.    if (ret_code != KRERR_NO_ERROR) {
  279.       return (ret_code);
  280.    } /*if*/
  281.  
  282.  
  283.    /* check links of recognition units
  284.    */
  285.    ret_code = kra1_LinksToRecUnits (&topo_ptr);
  286.  
  287.    if (ret_code != KRERR_NO_ERROR) {
  288.       return (ret_code);
  289.    } /*if*/
  290.  
  291.  
  292.    /* check links of delay units
  293.    */
  294.    ret_code = kra1_LinksToDelUnits (&topo_ptr);
  295.  
  296.    if (ret_code != KRERR_NO_ERROR) {
  297.       return (ret_code);
  298.    } /*if*/
  299.  
  300.  
  301.    /* check links of local reset units
  302.    */
  303.    ret_code = kra1_LinksToRstUnits (&topo_ptr);
  304.  
  305.    if (ret_code != KRERR_NO_ERROR) {
  306.       return (ret_code);
  307.    } /*if*/
  308.  
  309.  
  310.    /* check links of special function units
  311.    */
  312.    ret_code = kra1_LinksToSpecUnits (&topo_ptr);
  313.  
  314.    if (ret_code != KRERR_NO_ERROR) {
  315.       return (ret_code);
  316.    } /*if*/
  317.  
  318.  
  319.    ret_code = kra1_init_fix_weights ();
  320.  
  321.    return (ret_code);
  322.  
  323. } /* kra1_sort () */
  324. /*___________________________________________________________________________*/
  325.  
  326.  
  327.  
  328. /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
  329. int   kra1_getClassNo (void)
  330. {
  331.     TopoPtrArray   topo_ptr = Art1_del_layer;
  332.     int            i;
  333.  
  334.     /* if ART1 sorting wasn't performed then return negative value
  335.        to indicate mistake
  336.     */
  337.     if (topo_ptr == NULL) {
  338.        return (-1);
  339.     } /*if*/
  340.  
  341.     /* look for winning unit */
  342.     for (i = 1; (i <= Art1_NoOfRecUnits) || ((*topo_ptr)->act >= 0.9);
  343.          i++, topo_ptr++
  344.         );
  345.  
  346.     if ((i > Art1_NoOfRecUnits) && ((*topo_ptr)->act < 0.9)) {
  347.        return (-1);
  348.     } else {
  349.        return (topo_ptr - Art1_del_layer + 1);
  350.     } /*if*/
  351.  
  352. } /* kra1_getClassNo () */
  353. /*___________________________________________________________________________*/
  354.  
  355.  
  356.  
  357.  
  358.  
  359. /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
  360. static void   kra1_set_fix_weight (struct Unit *src_unit, struct Unit *trgt_unit, FlintType *weight)
  361. {
  362.  
  363.    if ((src_unit == NULL) || (trgt_unit == NULL)) {
  364.       return;
  365.    } /*if*/
  366.  
  367.    switch (src_unit->lln) {
  368.  
  369.    case ART1_INP_LAY:
  370.  
  371.       switch (trgt_unit->lln) {
  372.       case ART1_CMP_LAY:
  373.          *weight = ART1_LINK_INP_CMP;
  374.          break;
  375.       case ART1_SPEC_LAY:
  376.          switch (trgt_unit->lun) {
  377.          case ART1_G1_UNIT:
  378.             *weight = ART1_LINK_INP_G1;
  379.             break;
  380.          case ART1_RI_UNIT:
  381.             *weight = ART1_LINK_INP_RI;
  382.             break;
  383.          case ART1_G2_UNIT:
  384.             *weight = ART1_LINK_INP_G2;
  385.             break;
  386.          } /* switch */
  387.          break;
  388.       } /*switch*/
  389.       break;
  390.  
  391.    case ART1_CMP_LAY:
  392.  
  393.       switch (trgt_unit->lln) {
  394.       case ART1_SPEC_LAY:
  395.          *weight = ART1_LINK_CMP_RC;
  396.          break;
  397.       } /*switch*/
  398.       break;
  399.  
  400.    case ART1_REC_LAY:
  401.  
  402.       switch (trgt_unit->lln) {
  403.       case ART1_DEL_LAY:
  404.          *weight = ART1_LINK_REC_DEL;
  405.          break;
  406.       case ART1_SPEC_LAY:
  407.          *weight = ART1_LINK_REC_G1;
  408.          break;
  409.       } /*switch*/
  410.       break;
  411.  
  412.    case ART1_DEL_LAY:
  413.  
  414.       switch (trgt_unit->lln) {
  415.       case ART1_DEL_LAY:
  416.          *weight = ART1_LINK_DEL_DEL;
  417.          break;
  418.       case ART1_RST_LAY:
  419.          *weight = ART1_LINK_DEL_RST;
  420.          break;
  421.       case ART1_SPEC_LAY:
  422.          *weight = ART1_LINK_DEL_CL;
  423.          break;
  424.       } /*switch*/
  425.       break;
  426.  
  427.    case ART1_RST_LAY:
  428.  
  429.       switch (trgt_unit->lln) {
  430.       case ART1_REC_LAY:
  431.          *weight = ART1_LINK_RST_REC;
  432.          break;
  433.       case ART1_RST_LAY:
  434.          *weight = ART1_LINK_RST_RST;
  435.          break;
  436.       case ART1_SPEC_LAY:
  437.          *weight = ART1_LINK_RST_NCL;
  438.          break;
  439.       } /*switch*/
  440.       break;
  441.  
  442.    case ART1_SPEC_LAY:
  443.  
  444.       switch (src_unit->lun) {
  445.       case ART1_G1_UNIT:
  446.          *weight = ART1_LINK_G1_CMP;
  447.          break;
  448.       case ART1_RI_UNIT:
  449.          *weight = ART1_LINK_RI_RG;
  450.          break;
  451.       case ART1_RC_UNIT:
  452.          *weight = ART1_LINK_RC_RG;
  453.          break;
  454.       case ART1_RG_UNIT:
  455.          switch (trgt_unit->lln) {
  456.          case ART1_REC_LAY:
  457.             *weight = ART1_LINK_RG_REC;
  458.             break;
  459.          case ART1_RST_LAY:
  460.             *weight = ART1_LINK_RG_RST;
  461.             break;
  462.          case ART1_SPEC_LAY:
  463.             *weight = ART1_LINK_RG_CL;
  464.             break;
  465.          } /*switch*/
  466.          break;
  467.       case ART1_RHO_UNIT:
  468.          if (trgt_unit->lln == ART1_SPEC_LAY) {
  469.             switch (trgt_unit->lun) {
  470.             case ART1_RI_UNIT:
  471.                *weight = ART1_LINK_RHO_RI;
  472.                break;
  473.             case ART1_RHO_UNIT:
  474.                *weight = ART1_LINK_RHO_RHO;
  475.                break;
  476.             } /*switch*/
  477.          } /*if*/
  478.          break;
  479.       case ART1_G2_UNIT:
  480.          switch (trgt_unit->lln) {
  481.          case ART1_REC_LAY:
  482.             *weight = ART1_LINK_G2_REC;
  483.             break;
  484.          case ART1_SPEC_LAY:
  485.             *weight = ART1_LINK_G2_CL;
  486.             break;
  487.          } /*switch*/
  488.       } /*switch*/
  489.       break;
  490.  
  491.    } /* switch */
  492.  
  493.  
  494. } /* kra1_set_fix_weights () */
  495. /*___________________________________________________________________________*/
  496.  
  497.  
  498.  
  499. /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
  500. /* NOTE: Don't call this function unless net has been topologically sorted
  501.          with type ART1_TOPO_TYPE
  502. */
  503. static krui_err   kra1_init_fix_weights (void)
  504. {
  505.  
  506.    int                    ret_code  = KRERR_NO_ERROR;
  507.  
  508.    register struct Unit   *unit_ptr;
  509.    register struct Site   *site_ptr;
  510.    register struct Link   *link_ptr;
  511.  
  512.  
  513.  
  514.  
  515.    FOR_ALL_UNITS (unit_ptr) {
  516.  
  517.       if (UNIT_HAS_INPUTS (unit_ptr)) {
  518.  
  519.          if (UNIT_HAS_DIRECT_INPUTS (unit_ptr)) {
  520.  
  521.             FOR_ALL_LINKS (unit_ptr, link_ptr) {
  522.  
  523.                kra1_set_fix_weight (link_ptr->to, unit_ptr, &(link_ptr->weight));
  524.  
  525.             } /*FOR_ALL_LINKS*/
  526.  
  527.          } else {
  528.  
  529.             FOR_ALL_SITES_AND_LINKS (unit_ptr, site_ptr, link_ptr) {
  530.  
  531.                kra1_set_fix_weight (link_ptr->to, unit_ptr, &(link_ptr->weight));
  532.  
  533.             } /*FOR_ALL_SITES_AND_LINKS*/
  534.  
  535.          } /*if*/
  536.  
  537.       } /*if*/
  538.  
  539.    } /*FOR_ALL_UNITS*/
  540.  
  541.  
  542.    return (ret_code);
  543.  
  544. } /* kra1_init_fix_weights () */
  545. /*___________________________________________________________________________*/
  546.  
  547.  
  548.  
  549.  
  550.  
  551.  
  552. /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
  553. static int  kra1_get_NoOfRecUnits (void)
  554. {
  555.    register struct Unit  *unit_ptr;
  556.    int                   count           = 0;
  557.  
  558.  
  559.    FOR_ALL_UNITS (unit_ptr) {
  560.  
  561.       if (IS_SPECIAL_UNIT(unit_ptr)) {
  562.          count++;
  563.       } /*if*/
  564.  
  565.    } /*FOR_ALL_UNITS*/
  566.  
  567.    return (count);
  568.  
  569.  
  570. } /* kra1_get_NoOfRecUnits () */
  571. /*___________________________________________________________________________*/
  572.  
  573.  
  574.  
  575. /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
  576.  
  577. /* topo_ptr points on first position, where an input unit has to placed in
  578.    the topo ptr array
  579. */
  580.  
  581. static krui_err kra1_get_InpUnits (TopoPtrArray *topo_ptr)
  582. {
  583.    register struct Unit  *unit_ptr;
  584.  
  585.    krui_err              ret_code = KRERR_NO_ERROR;
  586.  
  587.  
  588.    FOR_ALL_UNITS (unit_ptr) {
  589.  
  590.       if (IS_INPUT_UNIT (unit_ptr)) {
  591.  
  592.          if (!(CHECK_ACT_FUNC(unit_ptr, ART1_ACTF_INP))) {
  593.             TOPO_MSG_ACT_FUNC (unit_ptr);
  594.          } /*if*/
  595.  
  596.          if (!(CHECK_OUT_FUNC(unit_ptr, ART1_OUTFUNC))) {
  597.             TOPO_MSG_OUT_FUNC (unit_ptr);
  598.          } /*if*/
  599.  
  600.          unit_ptr->lln = ART1_INP_LAY;
  601.          **topo_ptr = unit_ptr;
  602.          unit_ptr->flags |= UFLAG_REFRESH;
  603.          (*topo_ptr)++;
  604.       } /*if*/
  605.  
  606.    } /*FOR_ALL_UNITS*/
  607.  
  608.    return (ret_code);
  609.  
  610. } /* kra1_get_InpUnits () */
  611. /*___________________________________________________________________________*/
  612.  
  613.  
  614.  
  615. /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
  616.  
  617. static krui_err   kra1_get_CmpUnits (TopoPtrArray *topo_ptr, int *no_of_cmp_units)
  618. {
  619.    register struct Unit   *unit_ptr;
  620.    struct Unit            *unit_src_ptr;
  621.    register struct Link   *link_ptr;
  622.    struct Link            *link_src_ptr;
  623.  
  624.    bool                   is_cmp_unit;
  625.    bool                   has_link_to_inp;
  626.    bool                   has_links_to_other_than_inp;
  627.  
  628.    krui_err               ret_code = KRERR_NO_ERROR;
  629.  
  630.  
  631.    /* look for a recognition unit */
  632.  
  633.    for (unit_ptr=unit_array+1; !IS_SPECIAL_UNIT(unit_ptr); unit_ptr++);
  634.  
  635.  
  636.    /* the recognition unit is not supposed to have sites
  637.    */
  638.  
  639.    if (UNIT_HAS_SITES (unit_ptr)) {
  640.       TOPO_MSG_UNEXPECTED_SITES (unit_ptr);
  641.    } /*if*/
  642.  
  643.  
  644.    /* unit_ptr points to a recognition unit.
  645.       We follow the incoming links of this unit. If the source unit
  646.       we got by doing this has the following properties, it is a
  647.       comparison unit:
  648.          - has no sites
  649.          - has link to input unit
  650.          - has link to other than input unit
  651.    */
  652.  
  653.    FOR_ALL_LINKS (unit_ptr, link_ptr) {
  654.  
  655.       unit_src_ptr = link_ptr->to;
  656.  
  657.       if (UNIT_HAS_SITES (unit_src_ptr)) {
  658.          continue;
  659.       } /*if*/
  660.  
  661.       is_cmp_unit                  = FALSE;
  662.       has_link_to_inp              = FALSE;
  663.       has_links_to_other_than_inp  = FALSE;
  664.  
  665.       FOR_ALL_LINKS (unit_src_ptr, link_src_ptr) {
  666.  
  667.          if (IS_INPUT_UNIT(link_src_ptr->to)) {
  668.             has_link_to_inp = TRUE;
  669.          } else {
  670.             has_links_to_other_than_inp = TRUE;
  671.          } /*if*/
  672.  
  673.          if (has_link_to_inp && has_links_to_other_than_inp) {
  674.             is_cmp_unit = TRUE;
  675.             break;
  676.          } /*if*/
  677.  
  678.       } /*FOR_ALL_LINKS*/
  679.  
  680.  
  681.       if (is_cmp_unit) {
  682.  
  683.          if (!(CHECK_ACT_FUNC (unit_src_ptr, ART1_ACTF_CMP))) {
  684.             TOPO_MSG_ACT_FUNC (unit_src_ptr);
  685.          } /*if*/
  686.  
  687.          if (!(CHECK_OUT_FUNC (unit_src_ptr, ART1_OUTFUNC))) {
  688.             TOPO_MSG_OUT_FUNC (unit_src_ptr);
  689.          } /*if*/
  690.  
  691.          if (! (UNIT_REFRESHED (unit_src_ptr))) {
  692.  
  693.             unit_src_ptr->lln = ART1_CMP_LAY;
  694.             (*no_of_cmp_units)++;
  695.             **topo_ptr = unit_src_ptr;
  696.             unit_src_ptr->flags |= UFLAG_REFRESH;
  697.             (*topo_ptr)++;
  698.  
  699.          } /*if*/
  700.  
  701.       } /*if*/
  702.  
  703.    }/*FOR_ALL_LINKS*/
  704.  
  705.    return (ret_code);
  706.  
  707. } /* kra1_get_CmpUnits () */
  708. /*___________________________________________________________________________*/
  709.  
  710.  
  711.  
  712.  
  713.  
  714.  
  715.  
  716. /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
  717. static krui_err  kra1_get_RecUnits (TopoPtrArray *topo_ptr)
  718. {
  719.    register struct Unit  *unit_ptr;
  720.  
  721.    krui_err                   ret_code = KRERR_NO_ERROR;
  722.  
  723.    FOR_ALL_UNITS (unit_ptr) {
  724.  
  725.       if (IS_SPECIAL_UNIT (unit_ptr)) {
  726.  
  727.          if (!(CHECK_ACT_FUNC (unit_ptr, ART1_ACTF_REC))) {
  728.             TOPO_MSG_ACT_FUNC (unit_ptr);
  729.          } /*if*/
  730.  
  731.          if (!(CHECK_OUT_FUNC (unit_ptr, ART1_OUTFUNC))) {
  732.             TOPO_MSG_OUT_FUNC (unit_ptr);
  733.          } /*if*/
  734.  
  735.          if (!(UNIT_REFRESHED (unit_ptr))) {
  736.             unit_ptr->lln = ART1_REC_LAY;
  737.             **topo_ptr = unit_ptr;
  738.             unit_ptr->flags |= UFLAG_REFRESH;
  739.             (*topo_ptr)++;
  740.          } /*if*/
  741.  
  742.       } /*if*/
  743.  
  744.    } /*FOR_ALL_UNITS*/
  745.  
  746.    return (ret_code);
  747.  
  748. } /* kra1_get_RecUnits () */
  749. /*___________________________________________________________________________*/
  750.  
  751.  
  752.  
  753. /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
  754.  
  755. static krui_err   kra1_get_DelUnits (TopoPtrArray *topo_ptr, int *no_of_del_units)
  756. {
  757.    register struct Unit   *unit_ptr;
  758.    register struct Link   *link_ptr,
  759.                           *this_link = NULL;
  760.  
  761.    int                    count;
  762.  
  763.    bool                   checked_del_rec_units   = FALSE;
  764.    bool                   checked_first_del_unit  = FALSE;
  765.    bool                   checked_secnd_del_unit  = FALSE;
  766.    bool                   checked_third_del_unit  = FALSE;
  767.  
  768.  
  769.    krui_err               ret_code = KRERR_NO_ERROR;
  770.  
  771.  
  772.    /* first we determine the delay units that correspond to a recognition
  773.       unit. These are units that have exactly one incoming link, coming
  774.       from a recognition unit.
  775.    */
  776.  
  777.    FOR_ALL_UNITS (unit_ptr) {
  778.  
  779.       count     = 0;
  780.  
  781.       FOR_ALL_LINKS (unit_ptr, link_ptr) {
  782.  
  783.          count++;
  784.          this_link = link_ptr;
  785.  
  786.       } /* FOR_ALL_LINKS */
  787.  
  788.       if ((count == 1) && (this_link->to->lln == ART1_REC_LAY)) {
  789.  
  790.          if (!(CHECK_ACT_FUNC (unit_ptr, ART1_ACTF_DEL))) {
  791.             TOPO_MSG_ACT_FUNC (unit_ptr);
  792.          } /*if*/
  793.  
  794.          if (!(CHECK_OUT_FUNC (unit_ptr, ART1_OUTFUNC))) {
  795.             TOPO_MSG_OUT_FUNC (unit_ptr);
  796.          } /*if*/
  797.  
  798.          unit_ptr->lln = ART1_DEL_LAY;
  799.          unit_ptr->lun = ART1_DEL_REC_UNIT;
  800.          (*no_of_del_units)++;
  801.          **topo_ptr = unit_ptr;
  802.          (*topo_ptr)++;
  803.          unit_ptr->flags |= UFLAG_REFRESH;
  804.  
  805.       } /*if*/
  806.  
  807.    } /* FOR_ALL_UNITS*/
  808.  
  809.    checked_del_rec_units = TRUE;
  810.  
  811.  
  812.    /* Now we are looking for the first other delay unit which has got incoming
  813.       links from all delay units we determined above
  814.    */
  815.  
  816.    FOR_ALL_UNITS (unit_ptr) {
  817.  
  818.       if ((! (UNIT_REFRESHED (unit_ptr))) &&
  819.           (UNIT_HAS_DIRECT_INPUTS(unit_ptr))
  820.          )
  821.       {
  822.          count = 0;
  823.  
  824.          FOR_ALL_LINKS (unit_ptr, link_ptr) {
  825.  
  826.             if (link_ptr->to->lln == ART1_DEL_LAY) {
  827.                count++;
  828.                if (count > 1) {
  829.                   break;
  830.                } /*if*/
  831.             } else {
  832.                /* break FOR_ALL_LINKS */
  833.                break;
  834.             } /*if*/
  835.  
  836.          } /*FOR_ALL_LINKS*/
  837.  
  838.          if (count > 1) {
  839.  
  840.             if (!(CHECK_ACT_FUNC (unit_ptr, ART1_ACTF_D))) {
  841.                TOPO_MSG_ACT_FUNC (unit_ptr);
  842.             } /*if*/
  843.  
  844.             if (!(CHECK_OUT_FUNC (unit_ptr, ART1_OUTFUNC))) {
  845.                TOPO_MSG_OUT_FUNC (unit_ptr);
  846.             } /*if*/
  847.  
  848.  
  849.             unit_ptr->lln = ART1_DEL_LAY;
  850.             unit_ptr->lun = ART1_D1_UNIT;
  851.             checked_first_del_unit = TRUE;
  852.             (*no_of_del_units)++;
  853.             **topo_ptr = unit_ptr;
  854.             (*topo_ptr)++;
  855.             unit_ptr->flags |= UFLAG_REFRESH;
  856.  
  857.             /* break FOR_ALL_UNITS, 'cause the unit we searched for, was found
  858.             */
  859.             break;
  860.  
  861.          } /*if*/
  862.  
  863.       } /*if*/
  864.  
  865.    } /*FOR_ALL_UNITS*/
  866.  
  867.  
  868.    /* Now we look for the d2 unit
  869.    */
  870.  
  871.    FOR_ALL_UNITS (unit_ptr) {
  872.  
  873.       if (! (UNIT_REFRESHED (unit_ptr))) {
  874.  
  875.          count = 0;
  876.  
  877.          FOR_ALL_LINKS (unit_ptr, link_ptr) {
  878.  
  879.             count++;
  880.             this_link = link_ptr;
  881.  
  882.          } /*FOR_ALL_LINKS*/
  883.  
  884.          if ((count == 1) && (this_link->to->lln == ART1_DEL_LAY) &&
  885.              (this_link->to->lun == ART1_D1_UNIT)
  886.             )
  887.          {
  888.  
  889.                unit_ptr->lln = ART1_DEL_LAY;
  890.                unit_ptr->lun = ART1_D2_UNIT;
  891.                checked_secnd_del_unit = TRUE;
  892.                (*no_of_del_units)++;
  893.                unit_ptr->flags |= UFLAG_REFRESH;
  894.                **topo_ptr = unit_ptr;
  895.                (*topo_ptr)++;
  896.                break; /* terminate search for d2 unit */
  897.  
  898.          } /*if*/
  899.  
  900.       } /*if*/
  901.  
  902.    } /*FOR_ALL_UNITS*/
  903.  
  904.  
  905.  
  906.    /* At last  we look for the d3 unit
  907.    */
  908.  
  909.    FOR_ALL_UNITS (unit_ptr) {
  910.  
  911.       if (! (UNIT_REFRESHED (unit_ptr))) {
  912.  
  913.          count = 0;
  914.  
  915.          FOR_ALL_LINKS (unit_ptr, link_ptr) {
  916.  
  917.             count++;
  918.             this_link = link_ptr;
  919.  
  920.          } /*FOR_ALL_LINKS*/
  921.  
  922.          if ((count == 1) && (this_link->to->lln == ART1_DEL_LAY) &&
  923.              (this_link->to->lun == ART1_D2_UNIT)
  924.             )
  925.          {
  926.  
  927.                unit_ptr->lln = ART1_DEL_LAY;
  928.                unit_ptr->lun = ART1_D3_UNIT;
  929.                checked_third_del_unit = TRUE;
  930.                (*no_of_del_units)++;
  931.                unit_ptr->flags |= UFLAG_REFRESH;
  932.                **topo_ptr = unit_ptr;
  933.                (*topo_ptr)++;
  934.                break; /* terminate search for d3 unit */
  935.  
  936.          } /*if*/
  937.  
  938.       } /*if*/
  939.  
  940.    } /*FOR_ALL_UNITS*/
  941.  
  942.  
  943.    if (!checked_first_del_unit) {
  944.       TOPO_MSG_UNIT_MISSING ("d1");
  945.    } /*if*/
  946.  
  947.    if (!checked_secnd_del_unit) {
  948.       TOPO_MSG_UNIT_MISSING ("d2");
  949.    } /*if*/
  950.  
  951.    if (!checked_third_del_unit) {
  952.       TOPO_MSG_UNIT_MISSING ("d3");
  953.    } /*if*/
  954.  
  955.  
  956.    return (ret_code);
  957.  
  958. } /* kra1_get_DelUnits () */
  959. /*___________________________________________________________________________*/
  960.  
  961.  
  962.  
  963.  
  964. /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
  965.  
  966. static krui_err   kra1_get_RstUnits (TopoPtrArray *topo_ptr, int *no_of_rst_units)
  967. {
  968.    register struct Unit   *unit_ptr;
  969.    register struct Site   *site_ptr;
  970.    register struct Link   *link_ptr;
  971.  
  972.    bool                   has_link_to_itself,
  973.                           has_link_to_del_rec_unit;
  974.  
  975.    krui_err               ret_code = KRERR_NO_ERROR;
  976.  
  977.    /* determine rst units of which each one has sites, an incoming link
  978.       from itself , one of a delay unit that corresponds to a recognition
  979.       unit and one from the reset general unit (which wasn't determined yet)
  980.    */
  981.  
  982.    FOR_ALL_UNITS (unit_ptr) {
  983.  
  984.       if ((! (UNIT_REFRESHED (unit_ptr))) && (UNIT_HAS_SITES (unit_ptr))) {
  985.  
  986.          has_link_to_itself = FALSE;
  987.          has_link_to_del_rec_unit = FALSE;
  988.  
  989.          FOR_ALL_SITES_AND_LINKS (unit_ptr, site_ptr, link_ptr) {
  990.  
  991.             if (link_ptr->to == unit_ptr) {
  992.                has_link_to_itself = TRUE;
  993.             } else {
  994.                if ((link_ptr->to->lln == ART1_DEL_LAY) &&
  995.                    (link_ptr->to->lun == ART1_DEL_REC_UNIT)
  996.                   )
  997.                {
  998.                   has_link_to_del_rec_unit = TRUE;
  999.                } /*if*/
  1000.             } /*if*/
  1001.  
  1002.          } /*FOR_ALL_SITES_AND_LINKS*/
  1003.  
  1004.          if (has_link_to_itself && has_link_to_del_rec_unit) {
  1005.  
  1006.             if (!(CHECK_ACT_FUNC (unit_ptr, ART1_ACTF_RST))) {
  1007.                 TOPO_MSG_ACT_FUNC (unit_ptr);
  1008.             } /*if*/
  1009.  
  1010.             if (!(CHECK_OUT_FUNC (unit_ptr, ART1_OUTFUNC))) {
  1011.                  TOPO_MSG_OUT_FUNC (unit_ptr);
  1012.                } /*if*/
  1013.  
  1014.             unit_ptr->lln = ART1_RST_LAY;
  1015.             (*no_of_rst_units)++;
  1016.             **topo_ptr = unit_ptr;
  1017.             (*topo_ptr)++;
  1018.             unit_ptr->flags |= UFLAG_REFRESH;
  1019.  
  1020.          } /*if*/
  1021.  
  1022.       } /*if*/
  1023.  
  1024.    } /*FOR_ALL_UNITS*/
  1025.  
  1026.  
  1027.    return (ret_code);
  1028.  
  1029.  
  1030. } /* kra1_get_RstUnits () */
  1031. /*___________________________________________________________________________*/
  1032.  
  1033.  
  1034.  
  1035. /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
  1036. static krui_err   kra1_get_SpecUnits (TopoPtrArray *topo_ptr, int *no_of_spec_units)
  1037. {
  1038.    register struct Unit     *unit_ptr;
  1039.    register struct Site     *site_ptr;
  1040.    register struct Link     *link_ptr;
  1041.  
  1042.    TopoPtrArray             topo_spec_ptr = *topo_ptr;
  1043.  
  1044.    bool                     got_g1_unit    = FALSE;
  1045.    bool                     got_ri_unit    = FALSE;
  1046.    bool                     got_rc_unit    = FALSE;
  1047.    bool                     got_rg_unit    = FALSE;
  1048.    bool                     got_cl_unit    = FALSE;
  1049.    bool                     got_ncl_unit   = FALSE;
  1050.    bool                     got_rho_unit   = FALSE;
  1051.    bool                     got_g2_unit    = FALSE;
  1052.  
  1053.    bool                     links_to_rst_units,
  1054.                             links_to_del_units,
  1055.                             links_to_rec_units,
  1056.                             links_to_cmp_units,
  1057.                             links_to_rho_unit,
  1058.                             links_to_inp_units;
  1059.  
  1060.    krui_err                 ret_code = KRERR_NO_ERROR;
  1061.  
  1062.  
  1063.  
  1064.  
  1065.    FOR_ALL_UNITS (unit_ptr) {
  1066.  
  1067.       if (! (UNIT_REFRESHED (unit_ptr))) {
  1068.  
  1069.  
  1070.          if (UNIT_HAS_SITES (unit_ptr)) {
  1071.  
  1072.             /* This could be the g1 or the ri unit */
  1073.  
  1074.             /* This is the Gain 1 unit if it has links to
  1075.                a recognition unit
  1076.             */
  1077.             links_to_rec_units = FALSE;
  1078.             FOR_ALL_SITES_AND_LINKS (unit_ptr, site_ptr, link_ptr) {
  1079.                if (link_ptr->to->lln == ART1_REC_LAY) {
  1080.                   links_to_rec_units = TRUE;
  1081.                   break;
  1082.                } /*if*/
  1083.             } /*FOR_ALL_SITES_AND_LINKS*/
  1084.  
  1085.             if (links_to_rec_units) {
  1086.  
  1087.                if (!got_g1_unit) {
  1088.  
  1089.                   if (!(CHECK_ACT_FUNC (unit_ptr, ART1_ACTF_G1))) {
  1090.                      TOPO_MSG_ACT_FUNC (unit_ptr);
  1091.                   } /*if*/
  1092.  
  1093.                   if (!(CHECK_OUT_FUNC (unit_ptr, ART1_OUTFUNC))) {
  1094.                       TOPO_MSG_OUT_FUNC (unit_ptr);
  1095.                   } /*if*/
  1096.  
  1097.                   unit_ptr->lun = ART1_G1_UNIT;
  1098.                   unit_ptr->lln = ART1_SPEC_LAY;
  1099.                   (*topo_ptr)++;
  1100.                   (*no_of_spec_units)++;
  1101.                   unit_ptr->flags |= UFLAG_REFRESH;
  1102.                   *(topo_spec_ptr + 2) = unit_ptr;
  1103.                   got_g1_unit = TRUE;
  1104.                   continue;
  1105.  
  1106.                } /*if*/
  1107.  
  1108.             } else {
  1109.  
  1110.                /* This should be the ri unit */
  1111.                if (!got_ri_unit) {
  1112.  
  1113.                   if (!(CHECK_ACT_FUNC (unit_ptr, ART1_ACTF_RI))) {
  1114.                      TOPO_MSG_ACT_FUNC (unit_ptr);
  1115.                   } /*if*/
  1116.  
  1117.                   if (!(CHECK_OUT_FUNC (unit_ptr, ART1_OUTFUNC))) {
  1118.                       TOPO_MSG_OUT_FUNC (unit_ptr);
  1119.                   } /*if*/
  1120.  
  1121.                   unit_ptr->lun = ART1_RI_UNIT;
  1122.                   unit_ptr->lln = ART1_SPEC_LAY;
  1123.                   (*topo_ptr)++;
  1124.                   (*no_of_spec_units)++;
  1125.                   unit_ptr->flags |= UFLAG_REFRESH;
  1126.                   *(topo_spec_ptr + 3) = unit_ptr;
  1127.                   got_ri_unit = TRUE;
  1128.                   continue;
  1129.  
  1130.                } /*if*/
  1131.  
  1132.             } /*if*/
  1133.  
  1134.          } else {
  1135.  
  1136.             links_to_rst_units = FALSE;
  1137.             links_to_del_units = FALSE;
  1138.             links_to_cmp_units = FALSE;
  1139.             links_to_rho_unit  = FALSE;
  1140.             links_to_inp_units = FALSE;
  1141.  
  1142.             FOR_ALL_LINKS (unit_ptr, link_ptr) {
  1143.  
  1144.                switch (link_ptr->to->lln) {
  1145.                case ART1_INP_LAY:
  1146.                   links_to_inp_units = TRUE;
  1147.                   break;
  1148.                case ART1_CMP_LAY:
  1149.                   links_to_cmp_units = TRUE;
  1150.                   break;
  1151.                case ART1_DEL_LAY:
  1152.                   links_to_del_units = TRUE;
  1153.                   break;
  1154.                case ART1_RST_LAY:
  1155.                   links_to_rst_units = TRUE;
  1156.                   break;
  1157.                default:
  1158.                   if (unit_ptr == link_ptr->to) {
  1159.                      links_to_rho_unit = TRUE;
  1160.                   } /*if*/
  1161.                   break;
  1162.                } /* switch */
  1163.  
  1164.             } /*FOR_ALL_LINKS*/
  1165.  
  1166.             if ((links_to_inp_units) && (!got_g2_unit)) {
  1167.  
  1168.                if (!(CHECK_ACT_FUNC (unit_ptr, ART1_ACTF_G2))) {
  1169.                   TOPO_MSG_ACT_FUNC (unit_ptr);
  1170.                } /*if*/
  1171.  
  1172.                if (!(CHECK_OUT_FUNC (unit_ptr, ART1_OUTFUNC))) {
  1173.                   TOPO_MSG_OUT_FUNC (unit_ptr);
  1174.                } /*if*/
  1175.  
  1176.                unit_ptr->lun = ART1_G2_UNIT;
  1177.                unit_ptr->lln = ART1_SPEC_LAY;
  1178.                (*topo_ptr)++;
  1179.                (*no_of_spec_units)++;
  1180.                unit_ptr->flags |= UFLAG_REFRESH;
  1181.                *(topo_spec_ptr + 7) = unit_ptr;
  1182.                got_g2_unit = TRUE;
  1183.                continue;
  1184.             } /*if*/
  1185.  
  1186.             if (links_to_rho_unit && (!got_rho_unit)) {
  1187.                if (!(CHECK_ACT_FUNC (unit_ptr, ART1_ACTF_RHO))) {
  1188.                   TOPO_MSG_ACT_FUNC (unit_ptr);
  1189.                } /*if*/
  1190.  
  1191.                if (!(CHECK_OUT_FUNC (unit_ptr, ART1_OUTFUNC))) {
  1192.                   TOPO_MSG_OUT_FUNC (unit_ptr);
  1193.                } /*if*/
  1194.  
  1195.                unit_ptr->lun = ART1_RHO_UNIT;
  1196.                unit_ptr->lln = ART1_SPEC_LAY;
  1197.                (*topo_ptr)++;
  1198.                (*no_of_spec_units)++;
  1199.                unit_ptr->flags |= UFLAG_REFRESH;
  1200.                *(topo_spec_ptr + 6) = unit_ptr;
  1201.                got_rho_unit = TRUE;
  1202.                continue;
  1203.             } /*if*/
  1204.  
  1205.             if (links_to_cmp_units && (!got_rc_unit)) {
  1206.                if (!(CHECK_ACT_FUNC (unit_ptr, ART1_ACTF_RC))) {
  1207.                   TOPO_MSG_ACT_FUNC (unit_ptr);
  1208.                } /*if*/
  1209.  
  1210.                if (!(CHECK_OUT_FUNC (unit_ptr, ART1_OUTFUNC))) {
  1211.                   TOPO_MSG_OUT_FUNC (unit_ptr);
  1212.                } /*if*/
  1213.  
  1214.                unit_ptr->lun = ART1_RC_UNIT;
  1215.                unit_ptr->lln = ART1_SPEC_LAY;
  1216.                (*topo_ptr)++;
  1217.                (*no_of_spec_units)++;
  1218.                unit_ptr->flags |= UFLAG_REFRESH;
  1219.                *(topo_spec_ptr + 4) = unit_ptr;
  1220.                got_rc_unit = TRUE;
  1221.                continue;
  1222.             } /*if*/
  1223.  
  1224.             if (links_to_del_units && (!got_cl_unit)) {
  1225.                if (!(CHECK_ACT_FUNC (unit_ptr, ART1_ACTF_CL))) {
  1226.                   TOPO_MSG_ACT_FUNC (unit_ptr);
  1227.                } /*if*/
  1228.  
  1229.                if (!(CHECK_OUT_FUNC (unit_ptr, ART1_OUTFUNC))) {
  1230.                   TOPO_MSG_OUT_FUNC (unit_ptr);
  1231.                } /*if*/
  1232.  
  1233.                unit_ptr->lun = ART1_CL_UNIT;
  1234.                unit_ptr->lln = ART1_SPEC_LAY;
  1235.                (*topo_ptr)++;
  1236.                (*no_of_spec_units)++;
  1237.                unit_ptr->flags |= UFLAG_REFRESH;
  1238.                *topo_spec_ptr = unit_ptr;
  1239.                Art1_cl_unit = unit_ptr;
  1240.                got_cl_unit = TRUE;
  1241.                continue;
  1242.             } /*if*/
  1243.  
  1244.             if (links_to_rst_units && (!got_ncl_unit)) {
  1245.                if (!(CHECK_ACT_FUNC (unit_ptr, ART1_ACTF_NCL))) {
  1246.                   TOPO_MSG_ACT_FUNC (unit_ptr);
  1247.                } /*if*/
  1248.  
  1249.                if (!(CHECK_OUT_FUNC (unit_ptr, ART1_OUTFUNC))) {
  1250.                   TOPO_MSG_OUT_FUNC (unit_ptr);
  1251.                } /*if*/
  1252.  
  1253.                unit_ptr->lun = ART1_NCL_UNIT;
  1254.                unit_ptr->lln = ART1_SPEC_LAY;
  1255.                (*topo_ptr)++;
  1256.                (*no_of_spec_units)++;
  1257.                unit_ptr->flags |= UFLAG_REFRESH;
  1258.                *(topo_spec_ptr+1) = unit_ptr;
  1259.                Art1_nc_unit = unit_ptr;
  1260.                got_ncl_unit = TRUE;
  1261.                continue;
  1262.             } /*if*/
  1263.  
  1264.             if (!got_rg_unit) {
  1265.                if (!(CHECK_ACT_FUNC (unit_ptr, ART1_ACTF_RG))) {
  1266.                   TOPO_MSG_ACT_FUNC (unit_ptr);
  1267.                } /*if*/
  1268.  
  1269.                if (!(CHECK_OUT_FUNC (unit_ptr, ART1_OUTFUNC))) {
  1270.                   TOPO_MSG_OUT_FUNC (unit_ptr);
  1271.                } /*if*/
  1272.  
  1273.                unit_ptr->lun = ART1_RG_UNIT;
  1274.                unit_ptr->lln = ART1_SPEC_LAY;
  1275.                (*topo_ptr)++;
  1276.                (*no_of_spec_units)++;
  1277.                unit_ptr->flags |= UFLAG_REFRESH;
  1278.                *(topo_spec_ptr+5) = unit_ptr;
  1279.                got_rg_unit = TRUE;
  1280.                continue;
  1281.             } /*if*/
  1282.  
  1283.          } /*if*/
  1284.  
  1285.       } /*if*/
  1286.  
  1287.    } /*FOR_ALL_UNITS*/
  1288.  
  1289.    if (!got_cl_unit) {
  1290.       TOPO_MSG_UNIT_MISSING ("cl");
  1291.    } /*if*/
  1292.  
  1293.    if (!got_ncl_unit) {
  1294.       TOPO_MSG_UNIT_MISSING ("nc");
  1295.    } /*if*/
  1296.  
  1297.    if (!got_ri_unit) {
  1298.       TOPO_MSG_UNIT_MISSING ("ri");
  1299.    } /*if*/
  1300.  
  1301.    if (!got_rc_unit) {
  1302.       TOPO_MSG_UNIT_MISSING ("rc");
  1303.    } /*if*/
  1304.  
  1305.    if (!got_rg_unit) {
  1306.       TOPO_MSG_UNIT_MISSING ("rg");
  1307.    } /*if*/
  1308.  
  1309.    if (!got_g1_unit) {
  1310.       TOPO_MSG_UNIT_MISSING ("g1");
  1311.    } /*if*/
  1312.  
  1313.    if (!got_rho_unit) {
  1314.       TOPO_MSG_UNIT_MISSING ("rho");
  1315.    } /*if*/
  1316.  
  1317.    if (!got_g2_unit) {
  1318.       TOPO_MSG_UNIT_MISSING ("g2");
  1319.    } /*if*/
  1320.  
  1321.    return (ret_code);
  1322.  
  1323. } /* kra1_get_SpecUnits () */
  1324. /*___________________________________________________________________________*/
  1325.  
  1326.  
  1327. /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
  1328. static krui_err   kra1_TopoPtrArray (void)
  1329. {
  1330.    TopoPtrArray    topo_inp_cmp_sep,
  1331.                    topo_cmp_rec_sep,
  1332.                    topo_rec_del_sep,
  1333.                    topo_del_rst_sep,
  1334.                    topo_rst_spec_sep,
  1335.                    topo_ptr_array_end;
  1336.  
  1337.    int             ret_code = KRERR_NO_ERROR;
  1338.  
  1339.  
  1340.    topo_inp_cmp_sep = topo_ptr_array + NoOfInputUnits + 1;
  1341.    topo_cmp_rec_sep = topo_inp_cmp_sep + NoOfInputUnits + 1;
  1342.    topo_rec_del_sep = topo_cmp_rec_sep + Art1_NoOfRecUnits + 1;
  1343.    topo_del_rst_sep = topo_rec_del_sep + Art1_NoOfRecUnits + 4;
  1344.    topo_rst_spec_sep = topo_del_rst_sep + Art1_NoOfRecUnits + 1;
  1345.    topo_ptr_array_end = topo_rst_spec_sep + ART1_NO_OF_SPEC_UNITS + 1;
  1346.  
  1347.    if ((*topo_ptr_array != NULL) ||
  1348.        (*topo_inp_cmp_sep != NULL) ||
  1349.        (*topo_cmp_rec_sep != NULL) ||
  1350.        (*topo_rec_del_sep != NULL) ||
  1351.        (*topo_del_rst_sep != NULL) ||
  1352.        (*topo_rst_spec_sep != NULL) ||
  1353.        (*topo_ptr_array_end != NULL) ||
  1354.        (*(topo_ptr_array_end+1) != NULL)
  1355.       )
  1356.    {
  1357.       ART1_RETURN_NET_ERROR (ret_code);
  1358.    } /*if*/
  1359.  
  1360.  
  1361.    return (ret_code);
  1362.  
  1363.  
  1364. } /* kra1_TopoPtrArray */
  1365. /*___________________________________________________________________________*/
  1366.  
  1367.  
  1368.  
  1369. /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
  1370. static krui_err   kra1_Sites (void)
  1371. {
  1372.    register struct Unit   *unit_ptr;
  1373.    register struct Site   *site_ptr;
  1374.  
  1375.    TopoPtrArray           topo_rst_ptr,
  1376.                           topo_g1_ptr,
  1377.                           topo_ri_ptr;
  1378.  
  1379.    bool                   got_site1,
  1380.                           got_site2;
  1381.  
  1382.    krui_err               ret_code = KRERR_NO_ERROR;
  1383.  
  1384.  
  1385.  
  1386.    topo_rst_ptr = topo_ptr_array + 2*NoOfInputUnits + 2*Art1_NoOfRecUnits + 8;
  1387.    topo_g1_ptr  = topo_rst_ptr + Art1_NoOfRecUnits + 3;
  1388.    topo_ri_ptr  = topo_g1_ptr + 1;
  1389.  
  1390.    /* check sites of local reset units
  1391.    */
  1392.    while ((unit_ptr = *topo_rst_ptr++) != NULL) {
  1393.  
  1394.       got_site1 = FALSE;
  1395.       got_site2 = FALSE;
  1396.  
  1397.       if (UNIT_HAS_SITES (unit_ptr)) {
  1398.  
  1399.          FOR_ALL_SITES (unit_ptr, site_ptr) {
  1400.  
  1401.             if ((CHECK_SITE_FUNC (site_ptr, ART1_SITEF_RST_SELF)) && (!got_site1)) {
  1402.                got_site1 = TRUE;
  1403.                continue;
  1404.             } /*if*/
  1405.  
  1406.             if ((CHECK_SITE_FUNC (site_ptr, ART1_SITEF_RST_SIGNAL)) && (!got_site2)) {
  1407.                got_site2 = TRUE;
  1408.                continue;
  1409.             } /*if*/
  1410.  
  1411.             TOPO_MSG_SITE_FUNC (unit_ptr);
  1412.  
  1413.          } /*FOR_ALL_SITES*/
  1414.  
  1415.  
  1416.          if (!got_site1 || !got_site2) {
  1417.             TOPO_MSG_SITE_MISSING  (unit_ptr);
  1418.          } /*if*/
  1419.  
  1420.  
  1421.       } else {
  1422.  
  1423.          TOPO_MSG_UNEXPECTED_DIRECT_INPUTS (unit_ptr);
  1424.  
  1425.       } /*if*/
  1426.  
  1427.    } /*while*/
  1428.  
  1429.  
  1430.  
  1431.    /* Check sites of unit Gain 1 */
  1432.  
  1433.    if (UNIT_HAS_DIRECT_INPUTS (*topo_g1_ptr)) {
  1434.       TOPO_MSG_UNEXPECTED_DIRECT_INPUTS (*topo_g1_ptr);
  1435.    } /*if*/
  1436.  
  1437.    got_site1 = FALSE;
  1438.    got_site2 = FALSE;
  1439.  
  1440.    FOR_ALL_SITES (*topo_g1_ptr, site_ptr) {
  1441.  
  1442.       if ((CHECK_SITE_FUNC (site_ptr, ART1_SITEF_INP_G1)) && (!got_site1)) {
  1443.          got_site1 = TRUE;
  1444.          continue;
  1445.       } /*if*/
  1446.  
  1447.       if ((CHECK_SITE_FUNC (site_ptr, ART1_SITEF_REC_G1)) && (!got_site2)) {
  1448.          got_site2 = TRUE;
  1449.          continue;
  1450.       } /*if*/
  1451.  
  1452.       TOPO_MSG_SITE_FUNC (*topo_g1_ptr);
  1453.  
  1454.    } /*FOR_ALL_SITES*/
  1455.  
  1456.    if (!got_site1 || !got_site2) {
  1457.       TOPO_MSG_SITE_MISSING (*topo_g1_ptr);
  1458.    } /*if*/
  1459.  
  1460.  
  1461.    /* Check sites of unit RI */
  1462.  
  1463.    if (UNIT_HAS_DIRECT_INPUTS (*topo_ri_ptr)) {
  1464.       TOPO_MSG_UNEXPECTED_DIRECT_INPUTS (*topo_ri_ptr);
  1465.    } /*if*/
  1466.  
  1467.    got_site1 = FALSE;
  1468.    got_site2 = FALSE;
  1469.  
  1470.    FOR_ALL_SITES (*topo_ri_ptr, site_ptr) {
  1471.  
  1472.       if (CHECK_SITE_FUNC (site_ptr, ART1_SITEF_RI)) {
  1473.          if (!got_site1) {
  1474.             got_site1 = TRUE;
  1475.          } else {
  1476.             if (!got_site2) {
  1477.                got_site2 = TRUE;
  1478.             } else {
  1479.                TOPO_MSG_SITE_FUNC (*topo_ri_ptr);
  1480.             } /*if*/
  1481.          } /*if*/
  1482.       } /*if*/
  1483.  
  1484.    } /*FOR_ALL_SITES*/
  1485.  
  1486.    if (!got_site1 || !got_site2) {
  1487.       TOPO_MSG_SITE_MISSING (*topo_ri_ptr);
  1488.    } /*if*/
  1489.  
  1490.    return (ret_code);
  1491.  
  1492. } /* kra1_Sites () */
  1493. /*___________________________________________________________________________*/
  1494.  
  1495.  
  1496.  
  1497. /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
  1498. static krui_err   kra1_LinksToInpUnits (TopoPtrArray *topo_ptr)
  1499. {
  1500.    register struct Unit   *unit_ptr;
  1501.  
  1502.    krui_err               ret_code = KRERR_NO_ERROR;
  1503.  
  1504.    while ((unit_ptr = *(*topo_ptr)++) != NULL) {
  1505.  
  1506.       if (UNIT_HAS_INPUTS (unit_ptr)) {
  1507.          topo_msg.error_code = KRERR_I_UNITS_CONNECT;
  1508.          topo_msg.dest_error_unit = unit_ptr-unit_array;
  1509.          topo_msg.src_error_unit = 0;
  1510.          ret_code = topo_msg.error_code;
  1511.       } /*if*/
  1512.  
  1513.    } /*while*/
  1514.  
  1515.    return (ret_code);
  1516.  
  1517. } /* kra1_LinksToInpUnits () */
  1518. /*___________________________________________________________________________*/
  1519.  
  1520.  
  1521.  
  1522. /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
  1523. static krui_err   kra1_LinksToCmpUnits (TopoPtrArray *topo_ptr)
  1524. {
  1525.    register struct Unit     *unit_ptr;
  1526.    register struct Link     *link_ptr;
  1527.  
  1528.    int                      count_inp,
  1529.                             count_spec,
  1530.                             count_del;
  1531.  
  1532.  
  1533.    krui_err                 ret_code = KRERR_NO_ERROR;
  1534.  
  1535.  
  1536.    /* - each comparison unit has a link to exactly one input unit which itself
  1537.         is connected to only this comparison unit and no other.
  1538.       - each comparison unit is linked to the gain 1 unit
  1539.       - each comparison unit is linked to each delay unit that corresponds to
  1540.         a recognition unit
  1541.    */
  1542.  
  1543.    krart_deleteTouchFlags();
  1544.  
  1545.  
  1546.    while ((unit_ptr = *(*topo_ptr)++) != NULL) {
  1547.  
  1548.       if (UNIT_HAS_SITES (unit_ptr)) {
  1549.  
  1550.          TOPO_MSG_UNEXPECTED_SITES (unit_ptr);
  1551.  
  1552.       } else {
  1553.  
  1554.          count_inp = 0;
  1555.          count_spec = 0;
  1556.          count_del = 0;
  1557.  
  1558.          FOR_ALL_LINKS (unit_ptr, link_ptr) {
  1559.  
  1560.             switch (link_ptr->to->lln) {
  1561.             case ART1_DEL_LAY:
  1562.                if (link_ptr->to->lun == ART1_DEL_REC_UNIT) {
  1563.                   count_del++;
  1564.                } else {
  1565.                   TOPO_MSG_UNEXPECTED_LINK (link_ptr->to, unit_ptr);
  1566.                } /*if*/
  1567.                break;
  1568.             case ART1_INP_LAY:
  1569.                if ((UNIT_REFRESHED (link_ptr->to)) || (count_inp > 0)) {
  1570.                   TOPO_MSG_UNEXPECTED_LINK (link_ptr->to, unit_ptr);
  1571.                } /*if*/
  1572.                link_ptr->to->flags |= UFLAG_REFRESH;
  1573.                count_inp++;
  1574.                break;
  1575.             case ART1_SPEC_LAY:
  1576.                if (link_ptr->to->lun != ART1_G1_UNIT) {
  1577.                   TOPO_MSG_UNEXPECTED_LINK (link_ptr->to, unit_ptr);
  1578.                } /*if*/
  1579.                count_spec++;
  1580.                break;
  1581.             default :
  1582.                TOPO_MSG_UNEXPECTED_LINK (link_ptr->to, unit_ptr);
  1583.             } /* switch */
  1584.  
  1585.          } /*FOR_ALL_LINKS*/
  1586.  
  1587.          if ((count_inp != 1) || (count_spec != 1) ||
  1588.              (count_del != Art1_NoOfRecUnits)
  1589.             )
  1590.          {
  1591.             TOPO_MSG_LINK_MISSING (unit_ptr);
  1592.          } /*if*/
  1593.  
  1594.       } /*if*/
  1595.  
  1596.    } /*while*/
  1597.  
  1598.    return (ret_code);
  1599.  
  1600. } /* kra1_LinksToCmpUnits () */
  1601. /*___________________________________________________________________________*/
  1602.  
  1603.  
  1604.  
  1605.  
  1606. /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
  1607. static krui_err   kra1_LinksToRecUnits (TopoPtrArray *topo_ptr)
  1608. {
  1609.    register struct Unit     *unit_ptr;
  1610.    register struct Link     *link_ptr;
  1611.  
  1612.    int                      count_cmp;
  1613.    int                      count_rst;
  1614.    int                      count_rg;
  1615.    int                      count_g2;
  1616.  
  1617.    krui_err                 ret_code = KRERR_NO_ERROR;
  1618.  
  1619.  
  1620.    /* - each recognition unit is linked to all comparison units
  1621.       - each recognition unit is linked to the reset general unit
  1622.       - each recognition unit is linked to exactly one local reset unit which
  1623.         itself is linked to only this recognition unit.
  1624.    */
  1625.  
  1626.    krart_deleteTouchFlags();
  1627.  
  1628.  
  1629.    while ((unit_ptr = *(*topo_ptr)++) != NULL) {
  1630.  
  1631.       if (UNIT_HAS_SITES (unit_ptr)) {
  1632.  
  1633.          TOPO_MSG_UNEXPECTED_SITES (unit_ptr);
  1634.  
  1635.       } else {
  1636.  
  1637.          count_cmp = 0;
  1638.          count_rst = 0;
  1639.          count_rg  = 0;
  1640.          count_g2  = 0;
  1641.  
  1642.          FOR_ALL_LINKS (unit_ptr, link_ptr) {
  1643.  
  1644.             switch (link_ptr->to->lln) {
  1645.             case ART1_CMP_LAY:
  1646.                count_cmp++;
  1647.                break;
  1648.             case ART1_RST_LAY:
  1649.                if ((UNIT_REFRESHED (link_ptr->to)) || (count_rst > 0)) {
  1650.                   TOPO_MSG_UNEXPECTED_LINK (link_ptr->to, unit_ptr);
  1651.                } /*if*/
  1652.                link_ptr->to->flags |= UFLAG_REFRESH;
  1653.                count_rst++;
  1654.                break;
  1655.             case ART1_SPEC_LAY:
  1656.                switch (link_ptr->to->lun) {
  1657.                case ART1_RG_UNIT:
  1658.                   count_rg++;
  1659.                   break;
  1660.                case ART1_G2_UNIT:
  1661.                   count_g2++;
  1662.                   break;
  1663.                default:
  1664.                   TOPO_MSG_UNEXPECTED_LINK (link_ptr->to, unit_ptr);
  1665.                   break;
  1666.                } /*switch*/
  1667.                break;
  1668.             default :
  1669.                TOPO_MSG_UNEXPECTED_LINK (link_ptr->to, unit_ptr);
  1670.             } /* switch */
  1671.  
  1672.          } /*FOR_ALL_LINKS*/
  1673.  
  1674.          if ((count_rst != 1) || (count_rg != 1) || (count_g2 != 1) ||
  1675.              (count_cmp != NoOfInputUnits)
  1676.             )
  1677.          {
  1678.             TOPO_MSG_LINK_MISSING  (unit_ptr);
  1679.          } /*if*/
  1680.  
  1681.       } /*if*/
  1682.  
  1683.    } /*while*/
  1684.  
  1685.    return (ret_code);
  1686.  
  1687. } /* kra1_LinksToRecUnits () */
  1688. /*___________________________________________________________________________*/
  1689.  
  1690.  
  1691.  
  1692. /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
  1693. static krui_err   kra1_LinksToDelUnits (TopoPtrArray *topo_ptr)
  1694. {
  1695.    register struct Unit     *unit_ptr;
  1696.    register struct Link     *link_ptr;
  1697.  
  1698.    int                      count_rec;
  1699.    int                      count_del;
  1700.  
  1701.    krui_err                 ret_code = KRERR_NO_ERROR;
  1702.  
  1703.  
  1704.    /* There are different cases to distinguish
  1705.       1. the delay unit is one that corresponds to a recogniton unit
  1706.          then
  1707.               - it has only one incoming link which comes from the corresponding
  1708.                 recognition unit
  1709.  
  1710.       2. it is the first other delay unit then
  1711.               - it has links to all delay units that correspond to a
  1712.                 recognition unit
  1713.       3. it is the second other delay unit then
  1714.               - it has exactly one link to the first other delay unit
  1715.       4. it is the third other delay unit then
  1716.               - it has exactly one link to the second other delay unit.
  1717.    */
  1718.  
  1719.    while ((unit_ptr = *(*topo_ptr)++) != NULL) {
  1720.  
  1721.       if (UNIT_HAS_SITES (unit_ptr)) {
  1722.  
  1723.          TOPO_MSG_UNEXPECTED_SITES (unit_ptr);
  1724.  
  1725.       } else {
  1726.  
  1727.          switch (unit_ptr->lun) {
  1728.  
  1729.          case ART1_DEL_REC_UNIT:
  1730.  
  1731.             count_rec = 0;
  1732.  
  1733.             FOR_ALL_LINKS (unit_ptr, link_ptr) {
  1734.  
  1735.                if (link_ptr->to->lln == ART1_REC_LAY) {
  1736.  
  1737.                   if ((UNIT_REFRESHED (link_ptr->to)) || (count_rec > 0)) {
  1738.                      TOPO_MSG_UNEXPECTED_LINK (link_ptr->to, unit_ptr);
  1739.                   } else {
  1740.                      link_ptr->to->flags |= UFLAG_REFRESH;
  1741.                   } /*if*/
  1742.                   count_rec++;
  1743.  
  1744.                } else {
  1745.  
  1746.                   TOPO_MSG_UNEXPECTED_LINK (link_ptr->to, unit_ptr);
  1747.  
  1748.                } /*if*/
  1749.  
  1750.             } /*FOR_ALL_LINKS*/
  1751.  
  1752.             if (count_rec != 1) {
  1753.                TOPO_MSG_LINK_MISSING (unit_ptr);
  1754.             } /*if*/
  1755.  
  1756.             break;
  1757.  
  1758.          case ART1_D1_UNIT:
  1759.  
  1760.             count_del = 0;
  1761.  
  1762.             FOR_ALL_LINKS (unit_ptr, link_ptr) {
  1763.  
  1764.                if ((link_ptr->to->lln == ART1_DEL_LAY) &&
  1765.                    (link_ptr->to->lun == ART1_DEL_REC_UNIT)
  1766.                   )
  1767.                {
  1768.                   count_del++;
  1769.                } else {
  1770.                   TOPO_MSG_UNEXPECTED_LINK (link_ptr->to, unit_ptr);
  1771.                } /*if*/
  1772.  
  1773.             } /*FOR_ALL_LINKS*/
  1774.  
  1775.             if (count_del != Art1_NoOfRecUnits) {
  1776.                TOPO_MSG_LINK_MISSING (unit_ptr);
  1777.             } /*if*/
  1778.  
  1779.             break;
  1780.  
  1781.          case ART1_D2_UNIT:
  1782.  
  1783.             count_del = 0;
  1784.  
  1785.             FOR_ALL_LINKS (unit_ptr, link_ptr) {
  1786.  
  1787.                if ((link_ptr->to->lln == ART1_DEL_LAY) &&
  1788.                    (link_ptr->to->lun == ART1_D1_UNIT)
  1789.                   )
  1790.                {
  1791.                   count_del++;
  1792.                } else {
  1793.                   TOPO_MSG_UNEXPECTED_LINK (link_ptr->to, unit_ptr);
  1794.                } /*if*/
  1795.  
  1796.             } /*FOR_ALL_LINKS*/
  1797.  
  1798.             if (count_del != 1) {
  1799.                TOPO_MSG_LINK_MISSING (unit_ptr);
  1800.             } /*if*/
  1801.  
  1802.             break;
  1803.  
  1804.          case ART1_D3_UNIT:
  1805.  
  1806.             count_del = 0;
  1807.  
  1808.             FOR_ALL_LINKS (unit_ptr, link_ptr) {
  1809.  
  1810.                if ((link_ptr->to->lln == ART1_DEL_LAY) &&
  1811.                    (link_ptr->to->lun == ART1_D2_UNIT)
  1812.                   )
  1813.                {
  1814.                   count_del++;
  1815.                } else {
  1816.                   TOPO_MSG_UNEXPECTED_LINK (link_ptr->to, unit_ptr);
  1817.                } /*if*/
  1818.  
  1819.             } /*FOR_ALL_LINKS*/
  1820.  
  1821.             if (count_del != 1) {
  1822.                TOPO_MSG_LINK_MISSING (unit_ptr);
  1823.             } /*if*/
  1824.  
  1825.             break;
  1826.  
  1827.          default :
  1828.             ART1_RETURN_NET_ERROR (ret_code);
  1829.          } /* switch */
  1830.  
  1831.       } /*if*/
  1832.  
  1833.    } /*while*/
  1834.  
  1835.    return (ret_code);
  1836.  
  1837. } /* kra1_LinksToDelUnits () */
  1838. /*___________________________________________________________________________*/
  1839.  
  1840.  
  1841.  
  1842. /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
  1843. static krui_err   kra1_LinksToRstUnits (TopoPtrArray *topo_ptr)
  1844. {
  1845.    register struct Unit     *unit_ptr;
  1846.    register struct Link     *link_ptr;
  1847.  
  1848.    struct Site              *site_ptr,
  1849.                             *site_ptr1,
  1850.                             *site_ptr2;
  1851.  
  1852.  
  1853.  
  1854.    int                      count_rst;
  1855.    int                      count_spec;
  1856.    int                      count_del;
  1857.  
  1858.    krui_err                 ret_code = KRERR_NO_ERROR;
  1859.  
  1860.  
  1861.    /* - each local reset unit is linked to via site 1
  1862.       - each local reset unit is linked to the reset general unit via site 2
  1863.       - each local reset unit is linked to exactly one delay unit that
  1864.         corresponds to a recognition unit and which itself is linked
  1865.         to only this local reset unit, via site 2.
  1866.    */
  1867.  
  1868.    krart_deleteTouchFlags();
  1869.  
  1870.  
  1871.    while ((unit_ptr = *(*topo_ptr)++) != NULL) {
  1872.  
  1873.       if (UNIT_HAS_DIRECT_INPUTS (unit_ptr)) {
  1874.  
  1875.          TOPO_MSG_UNEXPECTED_DIRECT_INPUTS (unit_ptr);
  1876.  
  1877.       } else {
  1878.  
  1879.          count_rst = 0;
  1880.          count_spec = 0;
  1881.          count_del = 0;
  1882.  
  1883.          site_ptr1 = NULL;
  1884.          site_ptr2 = NULL;
  1885.  
  1886.          FOR_ALL_SITES_AND_LINKS (unit_ptr, site_ptr, link_ptr) {
  1887.  
  1888.             switch (link_ptr->to->lln) {
  1889.             case ART1_RST_LAY:
  1890.  
  1891.                count_rst++;
  1892.  
  1893.                if (link_ptr->to != unit_ptr) {
  1894.                   TOPO_MSG_UNEXPECTED_LINK (link_ptr->to, unit_ptr);
  1895.                } /*if*/
  1896.  
  1897.                site_ptr1 = site_ptr;
  1898.  
  1899.                if (site_ptr1 == site_ptr2) {
  1900.                   TOPO_MSG_LINK_TO_WRONG_SITE (link_ptr->to, unit_ptr);
  1901.                } /*if*/
  1902.  
  1903.                break;
  1904.  
  1905.             case ART1_DEL_LAY:
  1906.  
  1907.                if (UNIT_REFRESHED (link_ptr->to)) {
  1908.                   TOPO_MSG_UNEXPECTED_LINK (link_ptr->to, unit_ptr);
  1909.                } /*if*/
  1910.  
  1911.                link_ptr->to->flags |= UFLAG_REFRESH;
  1912.  
  1913.                count_del++;
  1914.  
  1915.                if ((site_ptr2 != NULL) && (site_ptr2 != site_ptr)) {
  1916.                   TOPO_MSG_LINK_TO_WRONG_SITE (link_ptr->to, unit_ptr);
  1917.                } /*if*/
  1918.  
  1919.                site_ptr2 = site_ptr;
  1920.  
  1921.                if (site_ptr1 == site_ptr2) {
  1922.                   TOPO_MSG_LINK_TO_WRONG_SITE (link_ptr->to, unit_ptr);
  1923.                } /*if*/
  1924.  
  1925.                break;
  1926.  
  1927.             case ART1_SPEC_LAY:
  1928.  
  1929.                if (link_ptr->to->lun != ART1_RG_UNIT) {
  1930.                   TOPO_MSG_UNEXPECTED_LINK (link_ptr->to, unit_ptr);
  1931.                } /*if*/
  1932.  
  1933.                count_spec++;
  1934.  
  1935.                if ((site_ptr2 != NULL) && (site_ptr2 != site_ptr)) {
  1936.                   TOPO_MSG_LINK_TO_WRONG_SITE (link_ptr->to, unit_ptr);
  1937.                } /*if*/
  1938.  
  1939.                site_ptr2 = site_ptr;
  1940.  
  1941.                if (site_ptr1 == site_ptr2) {
  1942.                   TOPO_MSG_LINK_TO_WRONG_SITE (link_ptr->to, unit_ptr);
  1943.                } /*if*/
  1944.  
  1945.                break;
  1946.  
  1947.             default :
  1948.                TOPO_MSG_UNEXPECTED_LINK (link_ptr->to, unit_ptr);
  1949.             } /* switch */
  1950.  
  1951.          } /*FOR_ALL_SITES_AND_LINKS*/
  1952.  
  1953.          if ((count_rst != 1) || (count_spec != 1) || (count_del != 1)) {
  1954.             TOPO_MSG_LINK_MISSING (unit_ptr);
  1955.          } /*if*/
  1956.  
  1957.       } /*if*/
  1958.  
  1959.    } /*while*/
  1960.  
  1961.    return (ret_code);
  1962.  
  1963. } /* kra1_LinksToRstUnits () */
  1964. /*___________________________________________________________________________*/
  1965.  
  1966.  
  1967.  
  1968.  
  1969. /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
  1970. static krui_err   kra1_LinksToSpecUnits (TopoPtrArray *topo_ptr)
  1971. {
  1972.    register struct Unit     *unit_ptr;
  1973.    register struct Link     *link_ptr;
  1974.  
  1975.    struct Site              *site_ptr,
  1976.                             *site_ptr1,
  1977.                             *site_ptr2;
  1978.  
  1979.  
  1980.  
  1981.    int                      count_rst;
  1982.    int                      count_del;
  1983.    int                      count_inp;
  1984.    int                      count_rec;
  1985.    int                      count_cmp;
  1986.    int                      count_ri;
  1987.    int                      count_rc;
  1988.    int                      count_rg;
  1989.    int                      count_rho;
  1990.    int                      count_g2;
  1991.  
  1992.    krui_err                 ret_code = KRERR_NO_ERROR;
  1993.  
  1994.  
  1995.    /* topo_ptr points to classified unit which has three links:
  1996.       1. from third other delay unit
  1997.       2. from reset general unit
  1998.       3. from gain 2 unit
  1999.    */
  2000.  
  2001.    unit_ptr = *(*topo_ptr)++;
  2002.  
  2003.    if (UNIT_HAS_SITES (unit_ptr)) {
  2004.       TOPO_MSG_UNEXPECTED_SITES (unit_ptr);
  2005.    } /*if*/
  2006.  
  2007.    count_del = 0;
  2008.    count_rg  = 0;
  2009.    count_g2  = 0;
  2010.  
  2011.    site_ptr1 = NULL;
  2012.    site_ptr2 = NULL;
  2013.  
  2014.    FOR_ALL_LINKS (unit_ptr, link_ptr) {
  2015.  
  2016.       switch (link_ptr->to->lln) {
  2017.       case ART1_DEL_LAY:
  2018.  
  2019.          count_del++;
  2020.  
  2021.          if (link_ptr->to->lun != ART1_D3_UNIT) {
  2022.             TOPO_MSG_UNEXPECTED_LINK (link_ptr->to, unit_ptr);
  2023.          } /*if*/
  2024.  
  2025.          break;
  2026.  
  2027.       case ART1_SPEC_LAY:
  2028.  
  2029.          switch (link_ptr->to->lun) {
  2030.          case ART1_RG_UNIT:
  2031.             count_rg++;
  2032.             break;
  2033.          case ART1_G2_UNIT:
  2034.             count_g2++;
  2035.             break;
  2036.          default:
  2037.             TOPO_MSG_UNEXPECTED_LINK (link_ptr->to, unit_ptr);
  2038.             break;
  2039.          } /*switch*/
  2040.  
  2041.          break;
  2042.  
  2043.       default :
  2044.          TOPO_MSG_UNEXPECTED_LINK (link_ptr->to, unit_ptr);
  2045.          break;
  2046.       } /* switch */
  2047.  
  2048.    } /*FOR_ALL_LINKS*/
  2049.  
  2050.    if ((count_del != 1) || (count_rg != 1) || (count_g2 != 1)) {
  2051.       TOPO_MSG_LINK_MISSING (unit_ptr);
  2052.    } /*if*/
  2053.  
  2054.  
  2055.    /* topo_ptr points to not classifiable unit which is linked to all
  2056.       local reset units
  2057.    */
  2058.  
  2059.    unit_ptr = *(*topo_ptr)++;
  2060.  
  2061.    if (UNIT_HAS_SITES (unit_ptr)) {
  2062.       TOPO_MSG_UNEXPECTED_SITES (unit_ptr);
  2063.    } /*if*/
  2064.  
  2065.    count_rst = 0;
  2066.  
  2067.    FOR_ALL_LINKS (unit_ptr, link_ptr) {
  2068.  
  2069.       if (link_ptr->to->lln != ART1_RST_LAY) {
  2070.          TOPO_MSG_UNEXPECTED_LINK (link_ptr->to, unit_ptr);
  2071.       } /*if*/
  2072.  
  2073.       count_rst++;
  2074.  
  2075.    } /*FOR_ALL_LINKS*/
  2076.  
  2077.    if (count_rst != Art1_NoOfRecUnits) {
  2078.       TOPO_MSG_LINK_MISSING (unit_ptr);
  2079.    } /*if*/
  2080.  
  2081.  
  2082.    /* topo_ptr points to Gain 1 unit which is linked to all input units
  2083.       via site 1 and to all recognition units via site 2
  2084.    */
  2085.  
  2086.    unit_ptr = *(*topo_ptr)++;
  2087.  
  2088.    if (UNIT_HAS_DIRECT_INPUTS (unit_ptr)) {
  2089.       TOPO_MSG_UNEXPECTED_DIRECT_INPUTS (unit_ptr);
  2090.    } /*if*/
  2091.  
  2092.    count_inp = 0;
  2093.    count_rec = 0;
  2094.  
  2095.    site_ptr1 = NULL;
  2096.    site_ptr2 = NULL;
  2097.  
  2098.    FOR_ALL_SITES_AND_LINKS (unit_ptr, site_ptr, link_ptr) {
  2099.  
  2100.       switch (link_ptr->to->lln) {
  2101.  
  2102.       case ART1_REC_LAY :
  2103.  
  2104.          count_rec++;
  2105.  
  2106.          if ((site_ptr2 != NULL) && (site_ptr2 != site_ptr)) {
  2107.             TOPO_MSG_LINK_TO_WRONG_SITE (link_ptr->to, unit_ptr);
  2108.          } /*if*/
  2109.  
  2110.          site_ptr2 = site_ptr;
  2111.  
  2112.          if (site_ptr1 == site_ptr2) {
  2113.             TOPO_MSG_LINK_TO_WRONG_SITE (link_ptr->to, unit_ptr);
  2114.          } /*if*/
  2115.  
  2116.          break;
  2117.  
  2118.       case ART1_INP_LAY :
  2119.  
  2120.          count_inp++;
  2121.  
  2122.          if ((site_ptr1 != NULL) && (site_ptr1 != site_ptr)) {
  2123.             TOPO_MSG_LINK_TO_WRONG_SITE (link_ptr->to, unit_ptr);
  2124.          } /*if*/
  2125.  
  2126.          site_ptr1 = site_ptr;
  2127.  
  2128.          if (site_ptr1 == site_ptr2) {
  2129.             TOPO_MSG_LINK_TO_WRONG_SITE (link_ptr->to, unit_ptr);
  2130.          } /*if*/
  2131.  
  2132.          break;
  2133.  
  2134.       default :
  2135.          TOPO_MSG_UNEXPECTED_LINK (link_ptr->to, unit_ptr);
  2136.  
  2137.       } /*switch*/
  2138.  
  2139.    } /*FOR_ALL_SITES_AND_LINKS*/
  2140.  
  2141.    if ((count_inp != NoOfInputUnits) || (count_rec != Art1_NoOfRecUnits)) {
  2142.       TOPO_MSG_LINK_MISSING (unit_ptr);
  2143.    } /*if*/
  2144.  
  2145.  
  2146.  
  2147.    /* topo_ptr points to reset I unit which is linked to all input units
  2148.       via one site and to the RHO unit via the other site
  2149.    */
  2150.  
  2151.    unit_ptr = *(*topo_ptr)++;
  2152.  
  2153.    if (UNIT_HAS_DIRECT_INPUTS (unit_ptr)) {
  2154.       TOPO_MSG_UNEXPECTED_DIRECT_INPUTS (unit_ptr);
  2155.    } /*if*/
  2156.  
  2157.    count_inp = 0;
  2158.    count_rho = 0;
  2159.  
  2160.    site_ptr1 = NULL;
  2161.    site_ptr2 = NULL;
  2162.  
  2163.    FOR_ALL_SITES_AND_LINKS (unit_ptr, site_ptr, link_ptr) {
  2164.  
  2165.       switch (link_ptr->to->lln) {
  2166.  
  2167.       case ART1_INP_LAY:
  2168.  
  2169.          count_inp++;
  2170.  
  2171.          if ((site_ptr1 != NULL) && (site_ptr1 != site_ptr)) {
  2172.             TOPO_MSG_LINK_TO_WRONG_SITE (link_ptr->to, unit_ptr);
  2173.          } /*if*/
  2174.  
  2175.          site_ptr1 = site_ptr;
  2176.  
  2177.          if (site_ptr1 == site_ptr2) {
  2178.             TOPO_MSG_LINK_TO_WRONG_SITE (link_ptr->to, unit_ptr);
  2179.          } /*if*/
  2180.  
  2181.          break;
  2182.  
  2183.       case ART1_SPEC_LAY:
  2184.  
  2185.          if (link_ptr->to->lun != ART1_RHO_UNIT) {
  2186.             TOPO_MSG_UNEXPECTED_LINK (link_ptr->to, unit_ptr);
  2187.          } /*if*/
  2188.  
  2189.          count_rho++;
  2190.  
  2191.          if ((site_ptr2 != NULL) && (site_ptr2 != site_ptr)) {
  2192.             TOPO_MSG_LINK_TO_WRONG_SITE (link_ptr->to, unit_ptr);
  2193.          } /*if*/
  2194.  
  2195.          site_ptr2 = site_ptr;
  2196.  
  2197.          if (site_ptr2 == site_ptr1) {
  2198.             TOPO_MSG_LINK_TO_WRONG_SITE (link_ptr->to, unit_ptr);
  2199.          } /*if*/
  2200.  
  2201.          break;
  2202.  
  2203.       default:
  2204.          TOPO_MSG_UNEXPECTED_LINK (link_ptr->to, unit_ptr);
  2205.  
  2206.       } /*switch*/
  2207.  
  2208.    } /*FOR_ALL_LINKS*/
  2209.  
  2210.    if ((count_inp != NoOfInputUnits) || (count_rho != 1)) {
  2211.       TOPO_MSG_LINK_MISSING (unit_ptr);
  2212.    } /*if*/
  2213.  
  2214.  
  2215.  
  2216.    /* topo_ptr points to reset C unit which is linked to all comparison units
  2217.    */
  2218.  
  2219.    unit_ptr = *(*topo_ptr)++;
  2220.  
  2221.    if (UNIT_HAS_SITES (unit_ptr)) {
  2222.       TOPO_MSG_UNEXPECTED_SITES (unit_ptr);
  2223.    } /*if*/
  2224.  
  2225.    count_cmp = 0;
  2226.  
  2227.    FOR_ALL_LINKS (unit_ptr, link_ptr) {
  2228.  
  2229.       if (link_ptr->to->lln != ART1_CMP_LAY) {
  2230.          TOPO_MSG_UNEXPECTED_LINK (link_ptr->to, unit_ptr);
  2231.       } /*if*/
  2232.  
  2233.       count_cmp++;
  2234.  
  2235.    } /*FOR_ALL_LINKS*/
  2236.  
  2237.    if (count_cmp != NoOfInputUnits) {
  2238.       TOPO_MSG_LINK_MISSING (unit_ptr);
  2239.    } /*if*/
  2240.  
  2241.  
  2242.    /* topo_ptr points to reset general unit which is linked to
  2243.       the reset I unit and the reset C unit
  2244.    */
  2245.  
  2246.    unit_ptr = *(*topo_ptr)++;
  2247.  
  2248.    if (UNIT_HAS_SITES (unit_ptr)) {
  2249.       TOPO_MSG_UNEXPECTED_SITES (unit_ptr);
  2250.    } /*if*/
  2251.  
  2252.    count_ri = 0;
  2253.    count_rc = 0;
  2254.  
  2255.    FOR_ALL_LINKS (unit_ptr, link_ptr) {
  2256.  
  2257.       if (link_ptr->to->lln != ART1_SPEC_LAY) {
  2258.          TOPO_MSG_UNEXPECTED_LINK (link_ptr->to, unit_ptr);
  2259.       } /*if*/
  2260.  
  2261.       if (link_ptr->to->lun == ART1_RI_UNIT) {
  2262.          count_ri++;
  2263.          continue;
  2264.       } /*if*/
  2265.  
  2266.       if (link_ptr->to->lun == ART1_RC_UNIT) {
  2267.          count_rc++;
  2268.          continue;
  2269.       } /*if*/
  2270.  
  2271.       TOPO_MSG_UNEXPECTED_LINK (link_ptr->to, unit_ptr);
  2272.  
  2273.    } /*FOR_ALL_LINKS*/
  2274.  
  2275.  
  2276.    if ((count_ri != 1) || (count_rc != 1)) {
  2277.       TOPO_MSG_LINK_MISSING (unit_ptr);
  2278.    } /*if*/
  2279.  
  2280.  
  2281.  
  2282.    /* topo_ptr points to RHO unit which has an incoming link
  2283.       from itself
  2284.    */
  2285.  
  2286.    unit_ptr = *(*topo_ptr)++;
  2287.  
  2288.    if (UNIT_HAS_SITES (unit_ptr)) {
  2289.       TOPO_MSG_UNEXPECTED_SITES (unit_ptr);
  2290.    } /*if*/
  2291.  
  2292.    count_rho = 0;
  2293.  
  2294.    FOR_ALL_LINKS (unit_ptr, link_ptr) {
  2295.       if ((link_ptr->to->lln == ART1_SPEC_LAY) &&
  2296.           (link_ptr->to->lun == ART1_RHO_UNIT)
  2297.          )
  2298.       {
  2299.          count_rho++;
  2300.       } else {
  2301.          TOPO_MSG_UNEXPECTED_LINK (link_ptr->to, unit_ptr);
  2302.       }  /*if*/
  2303.    } /*FOR_ALL_LINKS*/
  2304.  
  2305.    if (count_rho != 1) {
  2306.       TOPO_MSG_LINK_MISSING (unit_ptr);
  2307.    } /*if*/
  2308.  
  2309.  
  2310.    /* topo_ptr points to G2 unit which has incoming links
  2311.       from all input units
  2312.    */
  2313.  
  2314.    unit_ptr = *(*topo_ptr)++;
  2315.  
  2316.    if (UNIT_HAS_SITES (unit_ptr)) {
  2317.       TOPO_MSG_UNEXPECTED_SITES (unit_ptr);
  2318.    } /*if*/
  2319.  
  2320.    count_inp = 0;
  2321.  
  2322.    FOR_ALL_LINKS (unit_ptr, link_ptr) {
  2323.       if (link_ptr->to->lln == ART1_INP_LAY) {
  2324.          count_inp++;
  2325.       } else {
  2326.          TOPO_MSG_UNEXPECTED_LINK (link_ptr->to, unit_ptr);
  2327.       }  /*if*/
  2328.    } /*FOR_ALL_LINKS*/
  2329.  
  2330.    if (count_inp != NoOfInputUnits) {
  2331.       TOPO_MSG_LINK_MISSING (unit_ptr);
  2332.    } /*if*/
  2333.  
  2334.    return (ret_code);
  2335.  
  2336. } /* kra1_LinksToSpecUnits () */
  2337. /*___________________________________________________________________________*/
  2338.